import React, { Component } from 'react';
import DataSet, { DataView } from '@antv/data-set';
import { Chart, Geom, Label } from 'bizcharts';

export default class GeoJSONMap extends Component {
  constructor(props) {
    super(props);
    this.state = {
      width: 200,
      height: 200,
      dv: new DataView(),
    };
  }

  componentDidMount() {
    this.renderG2Map();
    window.addEventListener('resize', this.resize, { passive: true });
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
  }

  resize = () => {
    this.renderG2Map();
  };

  // 开始使用 G2 绘制地图
  renderG2Map = () => {
    const { mapJson: geoJSON } = this.props;
    const dv = this.processData(geoJSON);
    const { width: propsWidth, height: propsHeight } = this.props;
    // start: 计算地图的最佳宽高
    const longitudeRange = dv.range('longitude');
    const lantitudeRange = dv.range('lantitude');
    const ratio = (longitudeRange[1] - longitudeRange[0]) / (lantitudeRange[1] - lantitudeRange[0]);
    let width;
    let height;
    let maxSize;
    if (ratio > 1) {
      maxSize =
        propsWidth * window.viewportScale || (this.root ? this.root.parentNode.clientWidth : 200);
      width = maxSize;
      height = width / ratio;
    } else {
      maxSize =
        propsHeight * window.viewportScale || (this.root ? this.root.parentNode.clientHeight : 200);
      width = maxSize * ratio;
      height = maxSize;
    }
    // end: 计算地图的最佳宽高
    this.setState({
      width,
      height,
      dv,
    });
  };

  // 数据转换
  processData = geoJSON => {
    const mapData = {
      type: 'FeatureCollection',
      features: geoJSON,
    };
    // 构造数据
    const userData = [];
    if (geoJSON && geoJSON.length) {
      geoJSON.map(item => {
        const { name, adcode } = item.properties;
        userData.push({
          name,
          adcode,
          value: Math.round(Math.random() * 10000),
        });
      });
    }
    const ds = new DataSet();
    const geoDataView = ds.createView().source(mapData, {
      type: 'GeoJSON',
    }); // geoJSON 经纬度数据

    // 数据格式转换
    const dvData = ds.createView().source(userData);
    dvData.transform({
      type: 'geo.region',
      field: 'name',
      geoDataView,
      as: ['longitude', 'lantitude'],
    });
    return dvData;
  };

  getG2Instance = chart => {
    this.chart = chart;
  };

  render() {
    const { height, width, dv } = this.state;
    const { height: propsHeight, areaNumber, onMapClick } = this.props;

    return (
      <div
        style={{
          display: 'table',
          height: propsHeight ? propsHeight * window.viewportScale : undefined,
          width: '100%',
        }}
        ref={e => (this.root = e)}
      >
        <div
          id="map"
          style={{ textAlign: 'center', display: 'table-cell', verticalAlign: 'middle' }}
        >
          <Chart
            height={height}
            width={width}
            data={dv}
            padding={0}
            onPlotClick={({ data }) => {
              if (data && data._origin && data._origin.adcode && onMapClick) {
                onMapClick(data._origin.adcode, data._origin.name);
              }
            }}
            onLabelClick={({ data }) => {
              if (data && data.appendInfo && data.appendInfo.adcode && onMapClick) {
                onMapClick(data.appendInfo.adcode, data.appendInfo.name);
              }
            }}
            style={{ display: 'inline-block', textAlign: 'center' }}
            onGetG2Instance={this.getG2Instance}
          >
            <Geom
              type="polygon"
              position="longitude*lantitude"
              select={{
                // 设置是否允许选中以及选中样式
                mode: 'single', // 多选还是单选
                cancelable: false, // 选中是否允许取消
              }}
              style={{
                stroke: 'rgba(79,204,255,0.80)',
                lineWidth: 2,
                cursor: 'pointer',
                opacity: '0.8',
              }}
              color={[
                'adcode',
                adcode => {
                  if (areaNumber === adcode) {
                    return 'rgba(79,204,255,0.50)';
                  }
                  return '#151E4A';
                },
              ]}
            >
              <Label
                content="name"
                offset={0}
                textStyle={(name, { point }) => {
                  return {
                    fill: 'rgba(79,204,255,0.80)',
                    fontSize: 16 * window.viewportScale,
                    shadowBlur: 3 * window.viewportScale,
                    shadowColor: '#000',
                    cursor: 'pointer',
                    appendInfo: point,
                  };
                }}
              />
            </Geom>
          </Chart>
        </div>
      </div>
    );
  }
}
